package org.spruice;

import org.picocontainer.Characteristics;
import org.picocontainer.DefaultPicoContainer;
import org.spruice.reflect.MethodReplay;
import org.spruice.reflect.StringToValue;

import java.lang.reflect.Method;
import java.util.Properties;

public class BeanDefinitionBuilder {

    private final MethodReplay methodsToReplay;
    private final Properties props = new Properties();
    private String destroyMethod;
    private String initMethodName;
    private String name;
    private Class clzz;
    private Object instance;
    private String startMethod;
    private String stopMethod;

    public BeanDefinitionBuilder(String name, Class clzz, Object instance, StringToValue converters) {
        this.name = name;
        this.clzz = clzz;
        this.instance = instance;
        this.methodsToReplay = new MethodReplay(converters);
    }

    public void setDestroyMethodName(String destroyMethod) {
        this.destroyMethod = destroyMethod;
    }

    public void setInitMethodName(String initMethodName) {
        this.initMethodName = initMethodName;
    }

    public void addPropertyValue(Method propertyName, Object[] value) {
        methodsToReplay.add(propertyName, value);
    }

    public void addProperties(Properties p) {
        props.putAll(p);
    }

    public String getName() {
        return name;
    }

    public void setStartMethod(String startMethod) {
        this.startMethod = startMethod;
    }

    public void setStopMethod(String stopMethod) {
        this.stopMethod = stopMethod;
    }

    public void addTo(final DefaultPicoContainer context, ModuleLifecycle life) {
        if (instance == null) {
            context.as(Characteristics.CACHE)
                    .addComponent(name, clzz);
        } else {
            context.as(Characteristics.CACHE)
                    .addComponent(name, instance);
        }

        Runnable propApply = new Runnable() {
            public void run() {
                Object instance = context.getComponent(name);
                methodsToReplay.tranlateProperties(props, clzz);
                methodsToReplay.apply(instance);
            }
        };
        life.addInit(propApply);
        if (initMethodName != null) life.addInit(getName(), initMethodName);
        if (startMethod != null) life.addStart(getName(), startMethod);
        if (stopMethod != null) life.addStop(getName(), stopMethod);
        if (destroyMethod != null) life.addDestroy(getName(), destroyMethod);
    }
}
